using System;

using ICSharpCode.SharpZipLib.Zip;

namespace OpenXmlWriter.Packaging
{
  public abstract class OpenXmlPartContainer
  {
    protected OpenXmlPartCollection _parts;
    protected RelationshipCollection _relationships;
    protected OpenXmlPackage _openXmlPackage;
    protected PartsFactory _factory;
    protected Relationship _relationship;

    protected OpenXmlPartContainer() : this(null)
    {
    }

    protected OpenXmlPartContainer(OpenXmlPackage openXmlPackage)
    {
      _openXmlPackage = openXmlPackage;
      Initialize(_openXmlPackage);
    }

    protected void Initialize(OpenXmlPackage openXmlPackage)
    {
      _parts = new OpenXmlPartCollection();
      _relationships = new RelationshipCollection();
      if (openXmlPackage != null)
      {
        _factory = new PartsFactory(openXmlPackage, this);
      }
      else
      {
        _factory = new PartsFactory(null, this);
      }
    }

    public OpenXmlPart AddNewPart(Type partType)
    {
      OpenXmlPart part = PartsFactory.CreatePart(partType);
      part.AddTo(_parts);
      Relationship relationship = new Relationship(TargetPath, part.TargetPath, part.RelationshipType);
      part.Relationship = relationship;
      _relationships.Add(relationship);
      return part;
    }

    public OpenXmlPackage OpenXmlPackage
    {
      get
      {
        return _openXmlPackage;
      }
    }

    public OpenXmlPartCollection Parts
    {
      get
      {
        return _parts;
      }
    }

    public RelationshipCollection Relationships
    {
      get
      {
        return _relationships;
      }
    }

    public PartsFactory PartsFactory
    {
      get
      {
        return _factory;
      }
    }

    public Relationship Relationship
    {
      get
      {
        return _relationship;
      }
      set
      {
        _relationship = value;
      }
    }

    public void WriteEntry()
    {
      ((ZipOutputStream) OpenXmlPackage.GetStream()).PutNextEntry(new ZipEntry(TargetPath));
    }

    public abstract void AddTo(OpenXmlPartCollection parts);

    public abstract string TargetPath { get; }
  }
}